<?php


namespace app\api\model;


use app\common\library\IDMan;
use app\common\library\StatModel;
use app\common\model\BaseModel;
use common;
use ApiOper;

const BATTERY_CHANGE_ORDER_STATE_SUBMIT = 0;
const BATTERY_CHANGE_ORDER_STATE_FINISH = 100;

class BatteryChangeOrderModel extends BaseModel
{
    protected $name = 'battery_change_order';
    protected $pk = 'id';

    function submit($city_id, $bike_info, $bluetooth)
    {
        if ($bike_info['bus_state'] != 0) {
            if ($bike_info['bus_state'] == BIKE_BUS_STAT_OPER_REPARK) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆挪车中!"];
            }else if ($bike_info['bus_state'] == BIKE_BUS_STAT_USER_REPARK) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆换电中!"];
            }
            else if ($bike_info['bus_state'] == BIKE_BUS_STAT_BATTERY_CHANGE) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆换电中!"];
            } else {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆骑行中!"];
            }
        }

        $ID = IDMan::city_order_id($city_id);


        $bound_order_info = [
            'order_type' => ORDER_TYPE_BIKE_BATTERY_CHANGE,
            'order_id' => $ID,
            'op' => '换电开锁',
        ];

        if (!$bluetooth) {
            $ret = (new BikeMgr())->battery_unlock($city_id, $bike_info['id'], $bound_order_info);
            if ($ret[0] != 0) {
                $this->throw_myexception(ERROR_LOCK_ERROR, "开电池锁失败," . $ret[1] . "，请重试！");
            }
        } else {
            (new BikeMgr())->asyn_unlock_battery($city_id, $bike_info['id'], $bound_order_info);
        }


        $order_state = BATTERY_CHANGE_ORDER_STATE_SUBMIT;
        $start_park_id = null;
        $start_park_name = null;

        if (!empty($bike_info['park_id'])) {
            $start_park_id = $bike_info['park_id'];
            $start_park_name = $bike_info['park_name'];
        }
        $usrinfo = ApiOper::instance()->_user_info;

        $duration = 0;
        if (empty($bike_info['last_battery_change_order_end_time'])){
            $duration = 0;
        }
        else{
            $duration = time() - strtotime($bike_info['last_battery_change_order_end_time']);
        }


        $distance = 0;
        if (empty($bike_info['distance'])){
            $distance = 0;
        }
        else{
            $distance = $bike_info['distance'];
        }

        $order_info = [
            'id' => $ID,
            'city_id' => $city_id,
            'user_id' => $usrinfo['id'],
            'user_name' => $usrinfo['name'],
            'user_phone' => $usrinfo['phone'],
            'bike_id' => $bike_info['id'],
            'bike_sn' => $bike_info['sn'],
            'ecu_sn' => $bike_info['ecu_sn'],
            'imei' => $bike_info['imei'],
            'bike_model' => $bike_info['model'],
            'order_state' => $order_state,
            'coordinate' => $bike_info['coordinate'],
            'address' => $bike_info['address'],
            'park_id' => $start_park_id,
            'park_name' => $start_park_name,
            'create_time' => date('Y-m-d H:i:s'),
            'channel' => ApiOper::instance()->userinfo()['channel'],
            'last_battery_change_time' => $bike_info['last_battery_change_order_start_time'],
            'is_under_volt' => $bike_info['is_under_volt'],
            'battery_change_count' => $bike_info['battery_change_count'],
            'battery_capacity' => $bike_info['battery_capacity'],
            'battery_level_before' => $bike_info['battery_level'],
            'battery_level_after' => $bike_info['battery_level'],
            'distance' => $distance,
            'duration' => $duration,
        ];


        BikeModel::instance()->battery_change_start($city_id, $bike_info['id'], $order_info);

        self::create($order_info);

        (new BikeMgr())->asyn_update_bluetooth($bike_info);
        return [0, '', $order_info];
    }

    function finish($city_id, $order_id)
    {
        $order_info = $this->get_info($city_id, $order_id);
        if (empty($order_info)) {
            $this->throw_myexception(ERROR_QUERY_INFO, "查询订单失败!");
        }

        if ($order_info['order_state'] != BATTERY_CHANGE_ORDER_STATE_SUBMIT) {
            $this->throw_myexception(ERROR_STATE_DISMATCH, "订单已结束!");
        }
        //(new BikeBatteryCalc())->reset($order_info['bike_id']);
        (new BikeMgr())->query_bike_info_rt($order_info['imei']);

        $bike_info = BikeModel::instance()->get_info_by_id($order_info['bike_id']);
        if (empty($bike_info)) {
            $this->throw_myexception(ERROR_QUERY_INFO, "实时请求车辆信息失败!");
        }

        if ($bike_info['is_battery_locked'] == 0) {
            // throw_myexception(ERROR_QUERY_INFO, "电池锁未关!");
        }
        $incrment = $bike_info['battery_level'] - $order_info['battery_level_before'];
        $data = [
            'order_state' => BATTERY_CHANGE_ORDER_STATE_FINISH,
            'battery_level_after' => $bike_info['battery_level'],
            'increment' => $incrment,
        ];

        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];
        self::update($data, $where);


        BikeModel::instance()->battery_change_finish($city_id, $bike_info['id']);


        //更新记录
        $com_info =[
            'bike_sn' => $bike_info['sn'],
            'com_staff_type' => OPER_TYPE_OPS,
            'com_staff_id'   => $order_info['user_id'],
            'com_staff_name'   => $order_info['user_name'],
        ];

        (new BikeMgr())->asyn_warn_info($com_info);

        (new StatModel())->ops_month_changebattery_incr($city_id, $order_info['user_name'], 1);
        (new StatNewModel())->change_battery_incr($city_id, $incrment >= 70);

        return array_merge($order_info, $data);
    }

    function get_info($city_id, $order_id)
    {
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'user_id' => 'string',
            'user_name' => 'string',
            'user_phone' => 'string',
            'bike_id' => 'string',
            'bike_sn' => 'string',
            'bike_model' => 'string',
            'ecu_sn' => 'string',
            'imei' => 'string',
            'coordinate' => 'string',
            'address' => 'string',
            'park_id' => 'string',
            'park_name' => 'string',
            'battery_level_before' => 'int',
            'battery_level_after' => 'int',
            'battery_change_count' => 'int',
            'last_battery_change_time' => 'string',
            'is_under_volt' => 'int',
            'battery_capacity' => 'int',
            'battery_volt' => 'int',
            'increment' => 'int',
            'order_state' => 'int',
            'channel' => 'string',
            'create_time' => 'string',
            'battery_unlock_time' => 'string',
            'battery_lock_time' => 'string',
            'battery_off_time' => 'string',
            'battery_on_time' => 'string',
        ];


        $sfs = common::array_keys($selectlist);
        $beans = [
            'city_id'=>$city_id,
            'id'=>$order_id,
        ];

        return $this->where($beans)->field($sfs)->find();
    }

    function query_list($city_id, $condition, $pos, $limit)
    {
        $limit = min(2000, $limit);
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'user_id' => 'string',
            'user_name' => 'string',
            'user_phone' => 'string',
            'bike_id' => 'string',
            'bike_sn' => 'string',
            'bike_model' => 'string',
            'ecu_sn' => 'string',
            'imei' => 'string',
            'coordinate' => 'string',
            'address' => 'string',
            'park_id' => 'string',
            'park_name' => 'string',
            'battery_level_before' => 'int',
            'battery_level_after' => 'int',
            'battery_change_count' => 'int',
            'last_battery_change_time' => 'string',
            'is_under_volt' => 'int',
            'battery_capacity' => 'int',
            'battery_volt' => 'int',
            'increment' => 'int',
            'order_state' => 'int',
            'channel' => 'string',
            'create_time' => 'string',
            'battery_unlock_time' => 'string',
            'battery_lock_time' => 'string',
            'battery_off_time' => 'string',
            'battery_on_time' => 'string',
        ];
        $sfs =  common::array_keys($selectlist);
        $beans = [
            'city_id'=>$city_id,
        ];
        if (isset($condition['order_state'])) {
            $beans['order_state'] = $condition['order_state'];
        }

        if (isset($condition['is_order_finished'])) {
            if ($condition['is_order_finished']) {
                $beans['order_state'] = BATTERY_CHANGE_ORDER_STATE_FINISH;
            } else {
                $beans['order_state'] = ['<',BATTERY_CHANGE_ORDER_STATE_FINISH];
            }
        }

        if (isset($condition['user_id'])) {
            $beans['user_id'] = $condition['user_id'];
        }
        if (isset($condition['bike_id'])) {
            $beans['bike_id'] = $condition['bike_id'];
        }
        if (isset($condition['battery_increment_upper'])) {
            $beans['increment'] = ['<=',$condition['battery_increment_upper']];
        }
        if (isset($condition['battery_increment_lower'])) {
            $beans['increment'] = ['>=',$condition['battery_increment_lower']];
        }
        if (isset($condition['start_time'])) {
            $beans['create_time'] = ['>=',$condition['start_time']];
        }
        if (isset($condition['end_time'])) {
            $beans['create_time'] = ['<=',$condition['end_time']];
        }
        if (isset($condition['sk']) && !empty($condition['sk'])) {
            $sk = $condition['sk'];
            if (common::is_phone($sk)) {
                $beans['user_phone'] = $sk;
            } else if (common::is_name($sk)) {
                $beans['user_name'] = $sk;
            } else if (IDMan::is_bike_id($sk)) {
                $beans['bike_id'] = $sk;
            } else if (IDMan::is_bike_sn($sk)) {
                $beans['bike_sn'] = $sk;
            } else {
                return [];
            }
        }

        $rows = $this->where($beans)->field($sfs)->order('create_time','desc')->limit($pos,$limit)->select();
        $l = [];
        foreach ($rows as $row) {
            $l[] = common::sql_row($selectlist, $row);
        }
        return $l;
    }

    function update_info($city_id, $order_id, $data)
    {
        //hilog::debug('BatteryChangeOrderModel update #############################', $city_id, $order_id, $data);
        if (empty($data))
            return;


        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];
        self::update($data, $where);
    }


    //分析日志
    function analyz_month_date($city_id,$condition){
        $condition['is_order_finished'] = 1;
        $condition['user_id'] = ApiOper::instance()->userinfo()['id'];

        $list = $this->query_list($city_id,$condition,0,1000);

        $vaild = 0;
        $not_vaild = 0;
        foreach ($list as $val){
            if ($val['order_state'] == 100){
                $vaild++;
            }
            else{
                $not_vaild++;
            }
        }

        return [$vaild,$not_vaild,count($list)];
    }

    //分析
    function analyze($city_id,$condition,$use_phone = 1){
        $condition['is_order_finished'] = 1;

        $list = $this->query_list($city_id,$condition,0,5000);

        $repark_list =[];

        if ($use_phone == 1) {
            foreach ($list as $val) {
                if (!isset($repark_list[$val['user_phone']])) {
                    $repark_list[$val['user_phone']] = 1;
                } else
                    $repark_list[$val['user_phone']]++;
            }
        }
        else if ($use_phone == 2) {
            foreach ($list as $val) {
                if (!isset($repark_list[$val['user_id']])) {
                    $repark_list[$val['user_id']] = 1;
                } else
                    $repark_list[$val['user_id']]++;
            }
        }
        else{
            foreach ($list as $val) {
                if (!isset($repark_list[$val['user_name']])) {
                    $repark_list[$val['user_name']] = 1;
                } else
                    $repark_list[$val['user_name']]++;
            }
        }


        return $repark_list;
    }

    //修正
    function fix_battery_level_after($city_id,$order_id,$level){
        $order_info = $this->get($city_id,$order_id);

        if (empty($order_info)){
            return;
        }


        $incrment = $level - $order_info['battery_level_before'];
        if ($incrment <= $order_info['increment']){
            return;
        }

        $data=[
            'battery_level_after' => $level,
            'increment' => $incrment,
        ];

        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];

        self::update($data,$where);

    }
}